package controllers

import config.{MyAwait, MyRow}
import dao.{CmDao, CsDao, GenomeDao, QtlDao}
import javax.inject.Inject
import play.api.data.Form
import play.api.data.Forms._
import play.api.libs.json.Json
import play.api.mvc.{AbstractController, ControllerComponents}

import scala.concurrent.ExecutionContext

class SearchController @Inject()(csDao: CsDao,
                                 cmDao: CmDao,
                                 qtlDao: QtlDao,
                                 genomeDao: GenomeDao,
                                 cc: ControllerComponents)
                                (implicit exec: ExecutionContext) extends AbstractController(cc) with MyAwait with MyRow {

  def searchPage = Action { implicit request =>
    Ok(views.html.search.searchPage())
  }

  def searchPosPage = Action{implicit request=>
    Ok(views.html.search.searchPosPage())
  }

  case class GeneIdData(geneId: String)

  val GeneIdForm = Form(
    mapping(
      "geneId" -> text
    )(GeneIdData.apply)(GeneIdData.unapply)
  )

  def searchByGeneId = Action { implicit request =>
    val data = GeneIdForm.bindFromRequest.get.geneId
    val geneIds = data.trim.split(",").map(_.trim)
    val table = genomeDao.getByGeneIds(geneIds).toAwait.map(_.getMapByT())
    val geneids = csDao.getByGeneIds(table.map(_ ("geneid"))).toAwait.map(r => r.geneid -> r).toMap

    val t = table.map{x=>
      val species = x("species")
      if (species == "Cucumber") {
        val r = geneids(x("geneid"))
        val qtls = qtlDao.getByPos(r.chr.drop(3), r.start, r.end).toAwait.map { y =>
          s"<a href='/capdb/tools/qtlInfoPage?id=${y.id}' target='_blank'>${y.qtlId}</a>"
        }
        val qtl = if (qtls.nonEmpty) qtls.mkString(",") else "no"

        x ++ Map("qtl" -> qtl)
      } else {
        x ++ Map("qtl" -> "no")
      }
    }

    Ok(Json.toJson(t))
  }

  case class ConData(species:String,rna:String,tls:String,snp:String,m5c:String,m6a:String)

  val ConForm = Form(
    mapping(
      "species" -> text,
      "rna" -> text,
      "tls" -> text,
      "snp" -> text,
      "m5c" -> text,
      "m6a" -> text
    )(ConData.apply)(ConData.unapply)
  )

  def searchByCondition = Action { implicit request =>
    val data = ConForm.bindFromRequest.get

    val table = genomeDao.getByCon(data.species,data.rna,data.tls,data.snp,data.m5c,data.m6a).toAwait.map(_.getMapByT())
    val geneids = csDao.getByGeneIds(table.map(_ ("geneid"))).toAwait.map(r => r.geneid -> r).toMap

    val t = table.map{x=>
      val species = x("species")
      if (species == "Cucumber") {
        val r = geneids(x("geneid"))
        val qtls = qtlDao.getByPos(r.chr.drop(3), r.start, r.end).toAwait.map { y =>
          s"<a href='/capdb/tools/qtlInfoPage?id=${y.id}' target='_blank'>${y.qtlId}</a>"
        }
        val qtl = if (qtls.nonEmpty) qtls.mkString(",") else "no"

        x ++ Map("qtl" -> qtl)
      } else {
        x ++ Map("qtl" -> "no")
      }
    }

    Ok(Json.toJson(t))
  }

}
